package nevo.pkgs.neuro.bio;

import java.util.*;

import nevo.core.*;

public class NeuronObjectiveFunction implements ObjectiveFunction
{	
	/**
	 * The optimal voltage trace, initialized from the
	 * {@link #setDataToMatch(Double[], long) method}. 
	 */
	protected VoltageTrace traceToMatch;
	
		
	/**
	 * Set the optimal voltage trace.
	 * @param vt An array of voltage values (V)
	 * @param samprate The sampling rate of the data (Hz)
	 */
	public void setDataToMatch(Double[] vt, long samprate)
	{
		traceToMatch = new VoltageTrace(vt, samprate);
	}
	
	public double compute(Map<String, Object> modelOutput) throws Exception
	{
		Double[] trace = (Double[]) modelOutput.get("vtrace");
		long sampRate = (Long) modelOutput.get("samplingRate");
		VoltageTrace vtrace = new VoltageTrace(trace, sampRate);
		
		int k;
		double verr = 0, isierr = 0;
		
		//compute the norm of the voltage differences
		int maxlen = Math.min(trace.length, traceToMatch.v.length);
		for (k = 0; k < maxlen; k++)  verr += Math.pow(Math.abs(traceToMatch.v[k] - trace[k]), 2);
		verr = Math.sqrt(verr);
		
		//compute the norm of the ISI differences
		double isik;
		for (k = 0; k < traceToMatch.spikeStats.isi.length; k++)  {			
			if (vtrace.spikeStats.isi.length > k) {
				isik = vtrace.spikeStats.isi[k];
			} else { isik = 0; }
			isierr += Math.pow(Math.abs(traceToMatch.spikeStats.isi[k] - isik), 2);
		}
		isierr = Math.sqrt(isierr);
		
		System.err.println("verr=" + verr + ", isierr=" + isierr);
				
		return verr + isierr;
	}
}
